from euca2ools import Euca2ool, InstanceValidationError, Util
import logging
log = logging.getLogger(__name__)

from crv.tools.ivmmaker import IVMMaker
import sys,os
from subprocess import Popen,PIPE

class EucaVMMaker(IVMMaker):
    """
    This is the maker that start/stops VM in eucalyptus cloud
 
    @author Yushu Yao
    @version 0.1
    """
    ENVDICT={'EC2_URL'       :"http://192.168.0.7:8773/services/Eucalyptus",
             'EC2_ACCESS_KEY':'WKy3rMzOWPouVOxK1p3Ar1C2uRBwa2FBXnCw',
             'EC2_SECRET_KEY':'wyDTr0deHn1OCcxuEAp3kFycd0nr5YKzA0aQ'
             }

    def debug(self,str):
        #        self.debug(str)
        print str
        
    def __init__(self):
        super(EucaVMMaker, self).__init__("euca")
        self.__euca=Euca2ool()
        self.__euca.ec2_user_secret_key=EucaVMMaker.ENVDICT["EC2_SECRET_KEY"]
        self.__euca.ec2_user_access_key=EucaVMMaker.ENVDICT["EC2_ACCESS_KEY"]
        self.__euca.ec2_url=EucaVMMaker.ENVDICT["EC2_URL"]
        
        self.debug("EucaVMMaker::__init__(%s)"%(self.vmtype))

    def ready(self):
        return True

    def __callDescribe(self,idlist=[]):
        self.debug("EucaVMMaker:__callDescribe called, idlist=%s"%str(idlist))

        instance_ids = idlist
        try:
            for id in instance_ids:
                self.__euca.validate_instance_id(id)
        except InstanceValidationError:
            raise RuntimeError('Invalid instance id')

        euca_conn = self.__euca.make_connection()
        try:
            reservations = euca_conn.get_all_instances(instance_ids)
        except Exception, ex:
            raise RuntimeError('%s' % ex)

        check_instance_ids = False
        if(len(instance_ids) > 0):
            check_instance_ids = True
            
        instances={}
        
        for reservation in reservations:
            for instance in reservation.instances:
                if check_instance_ids:
                    if instance.id in instance_ids:
                        instances[instance.id]=instance
                else:
                    instances[instance.id]=instance

        return instances

    def isStopping(self,identifier):
        if identifier==None:
            return False
        ins=self.__callDescribe([identifier])
        return ins.has_key(identifier) and ins[identifier].state=="shutting-down"
    
    def isStarting(self,identifier):
        if identifier==None:
            return False
        ins=self.__callDescribe([identifier])
        return ins.has_key(identifier) and ins[identifier].state=="pending"

    def isStopped(self,identifier):
        if identifier==None:
            return True
        ins=self.__callDescribe([identifier])
        return not ins.has_key(identifier) or (ins.has_key(identifier) and ins[identifier].state=="terminated")

    def isStarted(self,identifier):
        if identifier==None:
            return False
        ins=self.__callDescribe([identifier])
        return not ins.has_key(identifier) or (ins.has_key(identifier) and ins[identifier].state=="running")
            
    def getIdentifiers(self):
        self.debug("EucaVMMaker:getIdentifiers called")
        instances=self.__callDescribe()        
        return instances.keys()

    def powerOn(self,userdatafile=None):

        self.debug("EucaVMMaker:poweronVM called")

        image_id = 'emi-7AD2165B'
        keyname = 'mykey'
        kernel_id = 'eki-7A1F1651'
        ramdisk_id = 'eri-571515B5'
        min_count = 1
        max_count = 1
        instance_type = 'm1.small' 
        group_names = ['at3'] 
        user_data = None
        addressing_type = None
        zone = None

        #read userdata
        if userdatafile!=None:
            USER_DATA_CHUNK_SIZE = 512
            user_data = "";
            user_data_file = open(userdatafile, "r")
            while 1:
                data = user_data_file.read(USER_DATA_CHUNK_SIZE)
                if not data:
                    break
                user_data += data
            user_data_file.close()
        
        euca_conn = self.__euca.make_connection()
	try:
            reservation = euca_conn.run_instances(image_id = image_id,
					      min_count = min_count,
					      max_count = max_count,
					      key_name = keyname,
					      security_groups = group_names,
					      user_data = user_data,
					      addressing_type = addressing_type,
					      instance_type = instance_type,
					      placement = zone,
					      kernel_id = kernel_id,
					      ramdisk_id = ramdisk_id)
        except Exception, ex:
            raise RuntimeError('%s' % ex)

        self.debug("EucaVMMaker:poweronVM: reservation=%s instance=%s"%(reservation.id,reservation.instances[0].id))
        
        return reservation.instances[0].id

    def powerOff(self,identifier):
        self.debug("EucaVMMaker:poweroffVM called: identifier=%s"%str(identifier))
        euca_conn = self.__euca.make_connection()
	try:
            instances = euca_conn.terminate_instances([identifier])
        except Exception, ex:
            raise RuntimeError('%s' % ex)


